package robocode;

import interfaces.IMetodosJason;
import jason.environment.grid.GridWorldModel;
import java.util.List;
import robocode.DadosRobos.RoboScaneado;
import tcp.enviarmsg.EnviarMsgTCP;
import tcp.enviarmsg.EnviarMsgTCP.TipoEnvio;

public class ModelSalvarRefem extends GridWorldModel {
	private IMetodosJason _imj;
	private long[] _ultimaExecucao;
	private long _tempoAvisarCadaRobo = 100L;
	private final boolean _rechamarCasoNull = false;
	private final boolean _aguardarCasoNull = true;
	private final long _tempoAguardarCasoNull = 100L;
	private boolean _ordemSeguirJaEnviada = false;
	private int _indiceSeguindo = -1;
	private CalculosRoboCode _cr;
	
    public ModelSalvarRefem(int Width, int Height, IMetodosJason imj, int numeroAgentes, int numeroRobos, CalculosRoboCode cr) {
        super(Width, Height, numeroAgentes); //3� parametro = n� agentes
        _cr = cr;
        _imj = imj;
        _imj.atualizarDadosRobosViaTCP();
        
        _ultimaExecucao = new long[numeroRobos];
		for (int i = 0; i < _ultimaExecucao.length; i++) {_ultimaExecucao[i]=0L;}
    }
    
    private void aguardar(){ aguardar(_tempoAguardarCasoNull); }
    private void aguardar(long tempo){ try { Thread.sleep(tempo); } catch (InterruptedException e) { e.printStackTrace(); } }
    
    public void AproximarRefem(RoboScaneado rb) throws Exception {
    	RoboScaneado refemSalvar = _imj.getRoboRefemSalvar();

    	if (rb == null || refemSalvar == null) {
    		if (_aguardarCasoNull) {aguardar();}
    		if (_rechamarCasoNull) AproximarRefem(rb); return;
    	}
    	
    	//Gera a lista de robos

    	List<RoboScaneado> robosInimigos = _imj.getRobosInimigos();
    	robosInimigos.add(0,rb);
    	    	    	
        List<String> ordens = _cr.getOrdensSalvarRefem(rb, refemSalvar, robosInimigos);
        enviarOrdem(ordens, rb.getNomeRobo());
    }
    
	public void VoltarMinhaArea(RoboScaneado rb) throws Exception {
		_imj.atualizarDadosRobosViaTCP();
		
		if (rb == null) {
    		if (_aguardarCasoNull) {aguardar();}
    		if (_rechamarCasoNull) VoltarMinhaArea(rb); return;
    	}
		
		List<RoboScaneado> robosInimigos = _imj.getRobosInimigos();
    	robosInimigos.add(0,rb);

		List<String> ordens = _cr.getOrdensVoltarMinhaArea(
				rb, robosInimigos,
				_cr.getXFinalRobo(_imj.getMLC(), _imj.getWCampo(), _imj.getHCampo()),
				_cr.getYFinalRobo(_imj.getMLC(), _imj.getWCampo(), _imj.getHCampo()));
		enviarOrdem(ordens, rb.getNomeRobo());
	}

	public void SeguirRoboSalvador(RoboScaneado rb, RoboScaneado refemSalvar) {
		int indice = _imj.getIndiceNomeRobo(rb.getNomeRobo());
		if (_ordemSeguirJaEnviada && _indiceSeguindo != indice) return;
		_imj.atualizarDadosRobosViaTCP();
		
		if (rb == null || refemSalvar == null) {
			if (_aguardarCasoNull) {aguardar();}
			if (_rechamarCasoNull) SeguirRoboSalvador(rb, refemSalvar);
			return;
		}
		
		_indiceSeguindo = indice;

		List<String> ordens = _cr.getOrdensRefemSeguirRoboSalvador(rb, refemSalvar);
		enviarOrdem(ordens, refemSalvar.getNomeRobo());
	}

	public void Defend(RoboScaneado rb, RoboScaneado refemPrender){
		_imj.atualizarDadosRobosViaTCP();
		
		//inimigo perto do refem, devo me aproximar do refem
		if (rb == null || refemPrender == null) {
			if (_aguardarCasoNull) {aguardar();}
			if (_rechamarCasoNull) Defend(rb, refemPrender);
			return;
		}
		
		List<RoboScaneado> robosInimigos = _imj.getRobosInimigos();
    	robosInimigos.add(0,rb);
		
		List<String> ordens = _cr.getOrdensAProximarRoboPrender(rb, refemPrender,robosInimigos);
		enviarOrdem(ordens, rb.getNomeRobo());
	}
	
	public void Atack(RoboScaneado rb, RoboScaneado rinimigo) {
		_imj.atualizarDadosRobosViaTCP();

		if (rb == null || rinimigo == null) {
			if (_aguardarCasoNull) {aguardar();}
			if (_rechamarCasoNull) Atack(rb, rinimigo);
			return;
		}
		List<String> ordens = _cr.getOrdensAtacar(rb, rinimigo);
		enviarOrdem(ordens, rb.getNomeRobo());
	}

	//remover no futuro
	public void BloquearAction(String nomeRobo, String nomeRoboInimigo) {
		_imj.atualizarDadosRobosViaTCP();

		int index = _imj.getIndiceLista(nomeRobo);
		RoboScaneado rb = _imj.getRobo(index);
		RoboScaneado rinimigo = _imj.getRoboInimigo(nomeRobo);
		if (rb == null || rinimigo == null) {
			if (_aguardarCasoNull) {aguardar();}
			if (_rechamarCasoNull) BloquearAction(nomeRobo, nomeRoboInimigo);
			return;
		}
	
		List<String> ordens = _cr.getOrdensBloquearAgSave(rb, rinimigo);
		enviarOrdem(ordens, nomeRoboInimigo);
	}
	
//    public void LudibriarInimigo(int idRobo) throws Exception {
//    	PercepcoesJason(idRobo);
//        List<String> ordens = new _cr(_imj).getOrdensLudibriarInimigo(idRobo);
//        if (ordens != null && ordens.size() > 0) enviarOrdem(ordens, 0);
//    }
 
//    public void BloquearAgSave(int idRobo) throws Exception {
//        if (VolteiMinhaArea(idRobo)) {
//    		_esr.removePercept(_imj.getAgInimigo(), Literal.parseLiteral("agenteProximo."));
//    		_esr.addPercept(_imj.getAgQuatroAcoes(), Literal.parseLiteral("voltei.")); 
//    		//_esr.Continuar(null);
//    		return; 
//    	}
//       
//        List<String> ordens = new _cr(_imj).getOrdensBloquearAgSave(idRobo);
//        if (ordens != null && ordens.size() > 0) enviarOrdem(ordens, 2); //envia ordens ao agente inimigo
//    }

    //----------------------------------------------------------------
    private void enviarOrdem(List<String> ordens, String nomeRobo){
    	if (ordens == null || ordens.size() <= 0) return; 
    	int indice = _imj.getIndiceNomeRobo(nomeRobo);
    	indice -= 1;
    	boolean eq0 = _ultimaExecucao[indice] == 0L;
    	if (eq0) {_ultimaExecucao[indice] = System.currentTimeMillis();}
    	long dif = System.currentTimeMillis() - _ultimaExecucao[indice];
    	if (dif >= _tempoAvisarCadaRobo || eq0) {
    		_ultimaExecucao[indice] = System.currentTimeMillis(); //update
	    	EnviarMsgTCP en = new EnviarMsgTCP(TipoEnvio.enviarOrdens, _imj.getPorta(indice), _imj.getIp(), _imj, indice);
	    	en.setOrdens(ordens);
	    	new Thread(en).start(); 
	    	//en.start();
	    	
	    	if (nomeRobo.equals("sample.RoboRefem")) {
	    		_ordemSeguirJaEnviada = true;
	    	}
    	}
    }
    
}